#include <iostream>
#include <memory>

using namespace std;

template<typename T> 
class Vector 
{ 
public:     

    using iterator = T *;

    iterator begin() const
    {
        return _start;
    }

    iterator end() const
    {
        return _finish;
    }


    Vector();     
    ~Vector();          
    void push_back(const T &);      
    void pop_back();         
    int size() const;     
    int capacity()const; 
private:     
    void reallocate();//重新分配内存,动态扩容要用的 
private:         
    static std::allocator<T> _alloc;          
    T *_start;                 //指向数组中的第一个元素     
    T *_finish;                //指向最后一个实际元素之后的那个元素     
    T *_end_of_storage;        //指向数组本身之后的位置 
};

template<typename T> 
allocator<T> Vector<T>::_alloc;          

    template<typename T> 
Vector<T>::Vector()
    :_start(nullptr)
    ,_finish(nullptr)
     ,_end_of_storage(nullptr)
{

}     


template<typename T> 
Vector<T>::~Vector(){
    if(_start){
        while(_start != _finish){
            _alloc.destroy(--_finish);
        }
        _alloc.deallocate(_start,capacity());
    }

}       


template<typename T> 
void Vector<T>::push_back(const T &value){
    //也可以这样比较，来确定容器是否存满
    //if(_finish == _end_of_storage) 
    if(size() == capacity()){
        //size等于capacity，扩容
        //先把大致思路写好，最后完成底层细节
        reallocate();
    }
    if(size() < capacity()){
        //在尾部添加元素
        _alloc.construct(_finish,value);
        _finish++;
    }

}   


template<typename T> 
void Vector<T>::pop_back(){
    if(size() > 0){
        _finish--;//因为_finish是指向元素的最后一位的下一位
        _alloc.destroy(_finish);
    }
}


template<typename T> 
int Vector<T>::size() const{
    return _finish - _start;
}   


template<typename T> 
int Vector<T>::capacity() const{
    return _end_of_storage - _start;
}


template<typename T> 
void Vector<T>::reallocate(){  //重新分配内存,动态扩容要用的 
    int oldCapacity = capacity();
    int newCapacity = oldCapacity ? 2 * oldCapacity : 1;
    //申请新空间
    T* temp = _alloc.allocate(newCapacity);


    if(_start){
        //copy将旧空间的对象拷贝到新空间
        /* copy(_start,_end_of_storage,temp); */
        uninitialized_copy(_start,_end_of_storage,temp);

        //销毁旧对象
        while(_start != _finish){
            //_alloc.destroy(_start);
            //_start++;
            //为了回收空间方便，所以使用_finish
            _finish--;
            _alloc.destroy(_finish);
        }

        //回收空间
        _alloc.deallocate(_start,oldCapacity);
    }
    /* _start = temp._start; */
    /* _finish = temp._finish; */
    /* _end_of_storage = temp._end_of_storage; */

    _start = temp;
    _finish = temp + oldCapacity;
    _end_of_storage = temp + newCapacity;
} 

    template <typename Container>
void printCapacity(const Container &con)
{
    cout << "size() = " << con.size() << endl;
    cout << "capacity() = " << con.capacity() << endl;
}


void test(){
    Vector<int> vec;
    printCapacity(vec);

    cout << endl;
    vec.push_back(1);
    printCapacity(vec);

    cout << endl;
    vec.push_back(2);
    printCapacity(vec);

    cout << endl;
    vec.push_back(3);
    printCapacity(vec);

    cout << endl;
    vec.push_back(4);
    printCapacity(vec);

    cout << endl;
    vec.push_back(5);
    printCapacity(vec);

    cout << endl;
    vec.push_back(1);
    printCapacity(vec);

    cout << endl;
    vec.push_back(2);
    printCapacity(vec);

    cout << endl;
    vec.push_back(8);
    printCapacity(vec);


    cout << endl << endl;
    for(auto &elem : vec)
    {
        cout << elem << "  ";
    }
    cout << endl;
}

int main()
{
    test();
    return 0;
}

